﻿using System.Collections.Generic;
using System.Linq;
using GC_FFW.BusinessEntities.Abstractions.Interfaces.Forecast;

namespace GC_FFW.BusinessEntities.Forecast
{
	public class PersonalConfrontationStatistics : IPersonalConfrontationStatistics
	{
		#region IPersonalConfrontationStatistics Members

		public string HomeTeamName { get; set; }

		public string AwayTeamName { get; set; }

		public IEnumerable<IMatch> Matches { get; set; }

		public IMatch LastTeamMatch
		{
			get
			{
				if (Matches == null || !Matches.Any()) return null;
				return Matches.OrderByDescending(m => m.Date).FirstOrDefault();
			}
		}

		public bool HasWinnerTeamStatistics
		{
			get
			{
				return HomeTeamWinsCount != AwayTeamWinsCount;
			}
		}

		public bool IsHomeTeamStatisticsWin
		{
			get
			{
				return HomeTeamWinsCount > AwayTeamWinsCount;
			}
		}

		public bool IsAwayTeamStatisticsWin
		{
			get
			{
				return HomeTeamWinsCount < AwayTeamWinsCount;
			}
		}

		public string WinnerTeamStatisticsName
		{
			get
			{
				return HasWinnerTeamStatistics
					? IsHomeTeamStatisticsWin
						? HomeTeamName
						: IsAwayTeamStatisticsWin ? AwayTeamName : string.Empty
					: string.Empty;
			}
		}

		public int HomeTeamWinsCount
		{
			get
			{
				return Matches != null && Matches.Any()
					? Matches.Count(m => m.HasWinner && m.WinnerName == HomeTeamName)
					: 0;
			}
		}

		public int AwayTeamWinsCount
		{
			get
			{
				return Matches != null && Matches.Any()
					? Matches.Count(m => m.HasWinner && m.WinnerName == AwayTeamName)
					: 0;
			}
		}

		public int DrawsCount
		{
			get
			{
				return Matches != null && Matches.Any()
					? Matches.Count(m => !m.HasWinner)
					: 0;
			}
		}

		public int HomeTeamTotalGoalsCount
		{
			get
			{
				return Matches != null && Matches.Any()
					? Matches.Sum(m => m.TeamGoalsCount(HomeTeamName))
					: 0;
			}
		}

		public int AwayTeamTotalGoalsCount
		{
			get
			{
				return Matches != null && Matches.Any()
					? Matches.Sum(m => m.TeamGoalsCount(AwayTeamName))
					: 0;
			}
		}

		public bool HasWinnerGreatAdvantage
		{
			get
			{
				return HasWinnerTeamStatistics &&
					((IsHomeTeamStatisticsWin && HomeTeamTotalGoalsCount - 2 * AwayTeamTotalGoalsCount >= AwayTeamTotalGoalsCount)
					||
					(IsAwayTeamStatisticsWin && AwayTeamTotalGoalsCount - 2 * HomeTeamTotalGoalsCount >= HomeTeamTotalGoalsCount));
			}
		}

		#endregion

		#region ICloneable Members

		public object Clone()
		{
			return new PersonalConfrontationStatistics
			{
				AwayTeamName = AwayTeamName != null ? AwayTeamName.Clone() as string : null,
				HomeTeamName = HomeTeamName != null ? HomeTeamName.Clone() as string : null,
				Matches = Matches != null
					? Matches.Select(m => m.Clone() as IMatch).ToList()
					: new List<IMatch>()
			};
		}

		#endregion

		#region IUpdateTeamOperations Members

		public void UpdateName(string newName, bool? isHomeTeam = null)
		{
			if (!isHomeTeam.HasValue) return;

			var oldValue = isHomeTeam.Value ? HomeTeamName : AwayTeamName;

			if (isHomeTeam.Value)
				HomeTeamName = newName;
			else
				AwayTeamName = newName;

			if (Matches != null)
			{
				foreach (var match in Matches)
				{
					if (match.HomeTeamName == oldValue)
						match.HomeTeamName = newName;
					else if (match.AwayTeamName == oldValue)
						match.AwayTeamName = newName;
				}
			}
		}

		#endregion
	}
}
